假如我們想增加的按鈕用來清除form
的資料,最快的方式是增加一個type=”reset”
的按鈕,這時候就用到兩個按鈕了,可以用到Blazor的核心觀念:Component抽離。
我們先在Shared資料夾新增一個Razor元件名為MyButton
,定義3個變數分別代表按鈕類型、按鈕樣式、按鈕名稱,注意要在屬性上面加上[Parameter]
,這是告訴Blazor這邊的值會來自叫用這個Component的上層Component。
接著移除標題的單向綁定,再將更新時間的div移到<EditForm>
外面,因為reset按鈕會清除整個form,我們不希望更新時間也被清除。最後在最下面使用兩個<MyButton>
Component,再輸入我們要的按鈕類型、按鈕樣式、按鈕名稱,這邊Blazor會告訴你還有哪些Parameter沒有被呼叫,如果有重複的Parameter也會有提示,所以不用擔心。
按下Reset按鈕,可以看到標題跟內容都被清除了。
要注意的是Parameter不支援混合razor及html字串的寫法,如果想這麼做建議用field
、property
或是string
方法回傳組合好的字串。
Parameter還有一點要避免,當Parent Component傳值到Child Component時,Parent Component若有StateHasChanged
相關動作,會將Parent Component及Child Component重新render,除非在Child Component用一個變數先接起來Parent Component傳來的值。
上面的文字似乎有看沒有懂,我們來看微軟給的例子,先建立一個Expander
Component,裡面做的事情很簡單,只要點擊<div>
就會收合或是展開內容。還有一個型別為RenderFragment
的ChildContent
,這是讓呼叫該Component的外部Component決定內容樣板。
接著在Post.razor叫用兩個Expander
,第一個有用到ChildContent
並放入<p>
元素,最後看到一個button帶有@onclick="StateHasChanged"
的事件,模擬Parent Component的StateHasChanged
事件。
打開網頁可以看到兩個Expander
的Expanded
皆為True
接著兩個Expander
都點一下,可以看到Expanded
都變False了
不過如果這時候點底下的button,會發現只有上面的Expanded
變成True,這是為什麼?
原因就在於Parent的state跟ChildContent
這個屬性,因為Parent的state改變了會重新render並將新資料傳給第一個Child,所以Expanded
被重設為true,第二個Child因為沒有接收ChildContent
所以不會重新render。
為了避免這問題,可以定義一個私有field
名為expanded
,當Component初始化時接下Parent傳來的Expanded
,之後的邏輯都根據expanded
處理。
Ref: Component parameters
Ref: ComponentBase.StateHasChanged Method